package pd;
import java.io.*;
import java.util.*;

import org.w3c.dom.*;
import org.xml.sax.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;

public class Storage extends Observable{
	
	private SwissSMSClient swissSMSClient;
	private String filepath;
	private HashMap<String,Vector<String>> settings;
	private Vector<String> services;
	
    public Storage(SwissSMSClient swissSMSClient, String filename){
    	this.swissSMSClient = swissSMSClient;
		if(System.getProperty("os.name").contains("Mac OS X")){
			filepath = System.getProperty("user.home") + "/Library/Preferences/" + filename;
		} else{
			filepath = System.getProperty("user.home") + "/" + filename;
		}
		
		services = new Vector<String>();
		services.add("Xtrazone");
		services.add("Hispeed");
		services.add("Sunrise");
		
		settings = new HashMap<String,Vector<String>>();
		settings.put("service", new Vector<String>());
		for(String service : services){
			settings.put(service, new Vector<String>());
		}
		settings.put("contacts", new Vector<String>());
		settings.put("history", new Vector<String>());
		
		if(System.getProperty("os.name").contains("Mac OS X")){
			settings.put("useappleaddrbook", new Vector<String>());
		}
		
		readSettings();
		initData();
    }
	
	public Vector<String> getSetting(String sett){
		return settings.get(sett);
	}
	
	public Vector<String> getServices(){
		return services;
	}
	
	public void clear(){
		for(String key : settings.keySet()){
			settings.get(key).clear();
		}
	}
	
	private void initData(){
		if(settings.get("service").size() == 0){
			settings.get("service").add(swissSMSClient.getDefaultService());
		}
		for(String service : services){
			if(settings.get(service).size() == 0){
				settings.get(service).add("");
				settings.get(service).add("");
			}
		}
		if(settings.containsKey("useappleaddrbook") && settings.get("useappleaddrbook").size() == 0){
			settings.get("useappleaddrbook").add("1");
		}
	}
	
	private void readSettings(){
		try {
			String sfile = readFile(filepath);
			if(sfile.matches("")){
				return;
			}
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document document = builder.parse(new InputSource(new StringReader(sfile)));
			NodeList ListChilds1 = document.getDocumentElement().getChildNodes();
			for(int i=0; i<ListChilds1.getLength(); i++){
				Node nodeChild = ListChilds1.item(i);
				if(null == nodeChild) continue;
				String sNodeName = nodeChild.getNodeName();
				if(null == sNodeName) continue;
				if(!settings.containsKey(sNodeName)) continue;
				NodeList ListChilds2 = nodeChild.getChildNodes();
				if(null == ListChilds2) continue;
				for(int j=0; j<ListChilds2.getLength(); j++){
					Node nodeChild2 = ListChilds2.item(j);
					if(null == nodeChild2 || null == nodeChild2.getFirstChild()) continue;
					String sNodeValue = nodeChild2.getFirstChild().getNodeValue();
					if(null == sNodeValue) continue;
					settings.get(sNodeName).add(sNodeValue);
				}
			}

		} catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public void saveSettings(){
		try{
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			DOMImplementation impl = builder.getDOMImplementation();

			Document xmldoc = impl.createDocument(null, "settings", null);
			
			Element root = xmldoc.getDocumentElement();
			for(String key : settings.keySet()){
				if(settings.get(key).size() == 0) continue;
				Element e1 = xmldoc.createElementNS(null, key);
				for(String value : settings.get(key)){
					Element e2 = xmldoc.createElementNS(null, "elem");
					Node n = xmldoc.createTextNode(value);
					e2.appendChild(n);
					e1.appendChild(e2);
				}
				root.appendChild(e1);
			}
			Source source = new DOMSource(xmldoc);
            StringWriter stringWriter = new StringWriter();
            Result result = new StreamResult(stringWriter);
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.transform(source, result);
			writeFile(filepath, stringWriter.getBuffer().toString());
			setChanged();
			notifyObservers();
		} catch(Exception e){
			e.printStackTrace();
		}
	}
	
	private static String readFile(String filepath){
		StringBuffer contents = new StringBuffer();
		try {
			File file = new File(filepath);
			if(!file.exists()){
				return "";
			}
			BufferedReader input =  new BufferedReader(new FileReader(file));
			try {
				String line = null;
				while (( line = input.readLine()) != null){
					contents.append(line);
					contents.append(System.getProperty("line.separator"));
				}
			}
			finally {
				input.close();
			}
		}
		catch (Exception e){
		  e.printStackTrace();
		}
		return contents.toString();
	}
	
	private static void writeFile(String filepath, String contents){
		try {
			File file = new File(filepath);
			if(!file.exists()){
				file.createNewFile();
			}
			Writer output = new BufferedWriter(new FileWriter(file));
			try {
				output.write(contents);
			}
			finally {
				output.close();
			}
		} catch(Exception e){
			e.printStackTrace();
		}
	}
	
	private static Vector<String> getAllFilesInFolder(String filepath){
		File file = new File(filepath);
		Vector<String> files = new Vector<String>();
		if(!file.exists()){
			return files;
		}
		if(file.isDirectory()){
            String internalNames[] = file.list();
            for(int i=0; i<internalNames.length; i++){
				files.addAll(getAllFilesInFolder(file.getAbsolutePath() + "/" + internalNames[i]));
			}
		} else if(!file.getName().startsWith(".")){
            files.add(file.getAbsolutePath());
        }
		return files;
	}

}
